package com.lq.order.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.UUID;
import com.lq.common.api.client.CartFeignClient;
import com.lq.common.api.client.ProductFeignClient;
import com.lq.common.api.dto.CartDTO;
import com.lq.common.api.dto.ProductDTO;
import com.lq.common.result.Result;
import com.lq.order.entity.Order;
import com.lq.order.entity.OrderItem;
import com.lq.order.entity.dto.OrderDTO;
import com.lq.order.enums.OrderStatusEnum;
import com.lq.order.mapper.OrderMapper;
import com.lq.order.service.IOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单表 服务实现类
 * </p>
 *
 * @author lq
 * @since 2025-08-22
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private CartFeignClient cartFeignClient;
    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private OrderItemServiceImpl orderItemService;

    @Override
    public List<Order> getOrdersByUserId(Long userId) {
        return this.lambdaQuery().eq(Order::getUserId, userId).list();
    }
    
    @Override
    public List<Order> getOrdersByStatus(Integer status) {
        return this.lambdaQuery().eq(Order::getStatus, status).list();
    }
    
    @Override
    public boolean createOrder(OrderDTO orderDTO) {
        Order order = BeanUtil.copyProperties(orderDTO, Order.class);
        List<Integer> cartItemIds = orderDTO.getCartItemIds();
        List<OrderItem> orderItems = new ArrayList<>();
        Long orderNo = UUID.randomUUID().getMostSignificantBits();
        BigDecimal sum = BigDecimal.ZERO;
        for (Integer cartItemId : cartItemIds){
            OrderItem orderItem =new OrderItem();
            CartDTO cartDTO = cartFeignClient.getCartById(Long.valueOf(cartItemId)).getData();
            Long productId = cartDTO.getProductId();
            ProductDTO productDTO =  productFeignClient.getProductById(productId).getData();
            Long quantity = Long.valueOf(cartDTO.getQuantity());
            orderItem.setOrderNo(String.valueOf(orderNo));
            orderItem.setProductId(productId);
            orderItem.setProductName(productDTO.getName());
            orderItem.setProductPrice(productDTO.getPrice());
            orderItem.setQuantity(cartDTO.getQuantity());
            BigDecimal totalPrice = productDTO.getPrice().multiply(new BigDecimal(quantity));
            orderItem.setTotalPrice(totalPrice);
            sum = sum.add(totalPrice);
            orderItem.setCreateTime(LocalDateTime.now());
            orderItem.setUpdateTime(LocalDateTime.now());
            orderItems.add(orderItem);
        }
        order.setOrderNo(String.valueOf(orderNo));
        order.setTotalAmount(sum);
        order.setPayAmount(BigDecimal.valueOf(0));
        order.setFreight(BigDecimal.valueOf(0));
        order.setStatus(OrderStatusEnum.WAIT_PAY.getCode());
        order.setUpdateTime(LocalDateTime.now());
        order.setCreateTime(LocalDateTime.now());
        save(order);
        orderItems.forEach(orderItem -> orderItem.setOrderId(order.getId()));
        orderItemService.saveBatchOrderItems(orderItems);
        return true;
    }
    
    @Override
    public boolean updateOrderStatus(Long orderId, Integer status) {
        return this.lambdaUpdate()
                .eq(Order::getId, orderId)
                .set(Order::getStatus, status)
                .set(Order::getUpdateTime, LocalDateTime.now())
                .update();
    }
    
    @Override
    public boolean cancelOrder(Long orderId) {
        return this.lambdaUpdate()
                .eq(Order::getId, orderId)
                .set(Order::getStatus, 4) // 4表示已取消
                .set(Order::getCancelTime, LocalDateTime.now())
                .set(Order::getUpdateTime, LocalDateTime.now())
                .update();
    }
}